<?php

declare(strict_types=1);

namespace App\CustHub\Mapper;

use App\CustHub\Model\ChRobot;
use Hyperf\Cache\Annotation\Cacheable;
use Hyperf\Config\Annotation\Value;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Model;
use Mine\Abstracts\AbstractMapper;
use Mine\MineModel;
use function Hyperf\Collection\data_get;

class ChRobotMapper extends AbstractMapper
{
    #[Value('cache.default.prefix')]
    protected string $prefix;

    public function assignModel()
    {
        $this->model = ChRobot::class;
    }

    /**
     * @param mixed $id
     * @return MineModel|Model|string|Builder|null
     */
    #[Cacheable(prefix: 'robot_info',value: 'id_#{id}',ttl: 15 * 60)]
    public function findById(mixed $id): ChRobot|Model|string|Builder|null
    {
        return $this->model::query()
            ->where('id',$id)
            ->first();
    }

    /**
     * 根据机器人KEY获取机器人信息
     * @param string $robotKey
     * @return ChRobot|Model|string|Builder|null
     */
//    #[Cacheable(prefix: 'robot_info_by_key',value: '#{robotKey}',ttl: 15 * 60)]
    public function findByRobotKey(string $robotKey): ChRobot|Model|string|Builder|null
    {
        return $this->model::query()
            ->where('robot_key',$robotKey)
            ->orWhere('uuid',$robotKey)
            ->first();
    }

    /**
     * 根据企微用户ID获取机器人信息
     * @param mixed $userId
     * @return ChRobot|Model|string|Builder|null
     */
    public function findByUserId(mixed $userId,int $mainUid): ChRobot|Model|string|Builder|null
    {
        return $this->model::query()
            ->withTrashed()
            ->where('main_uid',$mainUid)
            ->where('user_id',(string)$userId)
            ->first();
    }

    /**
     * 获取其他地方登录机器人ID
     * @param int $id
     * @param string $userId
     * @return \Hyperf\Tappable\HigherOrderTapProxy|mixed|null
     */
    public function getLoginElsewhereRobotId(int $id,string $userId): mixed
    {
        $robotId = $this->model::query()
            ->where('id','<>',$id)
            ->where('user_id',$userId)
            ->where('login_status',1)
            ->value('id');
        return $robotId;
    }

    /**
     * 根据ID批量获取机器人信息
     * @param array $ids
     * @param string $field
     * @return array|Collection|\Hyperf\Collection\Collection
     */
    public function findByIds(array $ids,string $field = '*'): array|Collection|\Hyperf\Collection\Collection
    {
        return $this->model::query()
            ->selectRaw($field)
            ->whereIn('id',$ids)
            ->get();
    }

    public function getIdsByGroupId(mixed $uid,mixed $groupId)
    {
        $query = $this->model::query()
            ->select(['id','uid','main_uid','nickname','avatar','corp_name','user_id','contact_num','room_num','login_status','is_auto_renewal'])
            ->withPermission((int) $uid);

        return $this->handleSearch($query,['group_id'=>$groupId])->pluck('id')->toArray();
    }

    /**
     * 清除缓存
     * @param mixed $id
     * @return void$
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @throws \RedisException
     */
    public function clearCache(mixed $id,string $robotKey = ''): void
    {
        $redis = redis();
        $keys[] = $this->prefix . 'robot_info:id_'.$id;
        if(!empty($robotKey)){
            $keys[] = $this->prefix . 'robot_info_by_key:'.$robotKey;
        }
        $redis->del($keys);
    }

    public function handleSearch(Builder $query, array $params): Builder
    {
        $id = data_get($params,'id');
        $loginStatus = data_get($params,'login_status');
        $subNickname = data_get($params,'sub_nickname');
        $corpId = data_get($params,'corp_id');
        $userId = (string)data_get($params,'user_id');
        $groupId = data_get($params,'group_id',-1);
        $htBindStatus = data_get($params,'ht_bind_status');

        if(filled($id)){
            $query->where('id',$id);
        }

        if(filled($loginStatus)){
            $query->where('login_status',$loginStatus);
        }

        if(!empty($subNickname)){
//            $query->whereHas('user',function ($query) use ($subNickname){
//                $query->whereRaw("MATCH (nickname) AGAINST ('{$subNickname}')");
//            });
            $query->where('nickname', 'like', '%'.$subNickname.'%');
        }

        if(filled($groupId)){
            if($groupId == 0){
                $query->doesntHave('groups');
            }elseif($groupId != -1){
                $query->whereHas('groups',function ($query) use ($groupId){
                    $query->where('group_id',$groupId);
                });
            }
        }

        if(!empty($corpId)){
            $query->where('corp_id',$corpId);
        }

        if(!empty($userId)){
            $query->where('user_id',$userId);
        }

        if(!empty($params['nickname'])){
            $query->where('nickname', 'like', '%'.$params['nickname'].'%');
        }

        if(filled($htBindStatus)){
            $query->where('ht_bind_status',$htBindStatus);
        }

        return $query;
    }
}